<!DOCTYPE html>
<html lang="en">
<!---
模型操作
1、实现整个的自动居中和自动满屏
2、在多个模型种，选择一个模型进行编辑
a.实现
-->

<head>
  <meta charset="UTF-8">
  <title>cube-oper</title>
  
  <script src="./js/pointUtil.js"></script>
  <!-- <script src="./js/three-scene.js"></script> -->
  <style>
    body {
      margin: 0;
      background-color: #000;
      color: #fff;
      font-family: Monospace;
      font-size: 13px;
      line-height: 24px;
      overscroll-behavior: none;
    }

    canvas {
      display: block;
    }

    #tooltip {
      position: absolute;
      background-color: rgba(0, 0, 0, 0.7);
      color: white;
      padding: 5px;
      border-radius: 5px;
      display: none;
      /* 默认隐藏 */
      pointer-events: none;
      font-size: 12px;
      white-space: break-spaces;
      z-index: 1;
    }
  </style>
</head>

<body>
  <!-- 创建用于显示提示的文本元素 -->
  <button type="button" onclick="scaleGeoTest(2,2)">测试</button> 
  <div id="container"></div>
  <div id="tooltip" onclick="tooltipCkick">
    
  </div>
  <script type="importmap">
    {
      "imports": {
        "three": "./js/threejs/three.module.js",
        "three/addons/": "./js/threejs/jsm/"
      }
    }
</script>
  <script type="module">
    import * as THREE from "./js/threejs/three.module.js";
    import threeUtil from './js/three-cube.js';
    import * as ThreeComm from './js/three-comm.js';

    import { VertexNormalsHelper } from 'three/addons/helper/VertexNormalsHelper.js';

    // 索引数组，定义每个面由哪些顶点构成 (每个面由两个三角形组成)
    const indicesCube = [
      0, 1, 2, 0, 2, 3, // 底面
      4, 6, 5, 4, 7, 6, // 顶面
      0, 4, 5, 0, 5, 1, // 右面
      1, 5, 6, 1, 6, 2, // 前面
      2, 6, 7, 2, 7, 3, // 上面
      3, 7, 4, 3, 4, 0, // 背面
    ];


    var optCubes = [
      { "data": { "id": "101", "type": "L", "name": "L01", "color": "#FF0000" }, "points": [{ "x": 20, "y": 0 }, { "x": 190, "y": 0 }, { "x": 190, "y": 20 }, { "x": 20, "y": 20 }] },
      { "data": { "id": "101", "type": "Z", "name": "L02", "color": "#A52A2A" }, "points": [{ "x": 190, "y": 0 }, { "x": 240, "y": 50 }, { "x": 220, "y": 50 }, { "x": 190, "y": 20 }] },
      { "data": { "id": "101", "type": "L", "name": "L03", "color": "#5F9EA0" }, "points": [{ "x": 220, "y": 50 }, { "x": 240, "y": 50 }, { "x": 240, "y": 150 }, { "x": 220, "y": 150 }] },
      { "data": { "id": "101", "type": "Z", "name": "L04", "color": "#7FFF00" }, "points": [{ "x": 150, "y": 150 }, { "x": 240, "y": 150 }, { "x": 220, "y": 170 }, { "x": 150, "y": 170 }] },
      { "data": { "id": "101", "type": "Z", "name": "Z01", "color": "#6495ED" }, "points": [{ "x": 130, "y": 150 }, { "x": 150, "y": 150 }, { "x": 150, "y": 170 }, { "x": 130, "y": 170 }] },
      { "data": { "id": "101", "type": "L", "name": "L05", "color": "#008B8B" }, "points": [{ "x": 50, "y": 150 }, { "x": 130, "y": 150 }, { "x": 130, "y": 170 }, { "x": 50, "y": 170 }] },
      { "data": { "id": "101", "type": "Z", "name": "L06", "color": "#006400" }, "points": [{ "x": 50, "y": 150 }, { "x": 50, "y": 170 }, { "x": 30, "y": 170 }, { "x": 30, "y": 160 }] },
      { "data": { "id": "101", "type": "L", "name": "L07", "color": "#8B008B" }, "points": [{ "x": 20, "y": 90 }, { "x": 50, "y": 150 }, { "x": 20, "y": 160 }, { "x": 0, "y": 100 }] },
      { "data": { "id": "101", "type": "Z", "name": "L08", "color": "#228B22" }, "points": [{ "x": 0, "y": 20 }, { "x": 20, "y": 0 }, { "x": 20, "y": 90 }, { "x": 0, "y": 100 }] },
      { "data": { "id": "101", "type": "L", "name": "L09", "color": "#FFA500" }, "points": [{ "x": 130, "y": 20 }, { "x": 150, "y": 20 }, { "x": 150, "y": 150 }, { "x": 130, "y": 150 }] },
      { "data": { "id": "101", "type": "DB", "name": "DB1", "color": "#FFA500" }, "points": [{ "x": 70, "y": 70 }, { "x": 90, "y": 70 }, { "x": 90, "y": 110 }, { "x": 70, "y": 110 }] },
      { "data": { "id": "101", "type": "DB", "name": "DB2", "color": "#4B0082" }, "points": [{ "x": 180, "y": 90 }, { "x": 200, "y": 90 }, { "x": 200, "y": 110 }, { "x": 180, "y": 110 }] },
    ];

    let { scene, camera, renderer, container,dragControls,dragObjects,orbitControls} = threeUtil.initScene();

    var curFaceIdx = null;//当前选择模型的面
    var curMarker  = null;//当前选择的标志物
    var curPosition= null;//当前选择的点
    var hCubes = []
    var hImgs = []
    var optCube = optCubes[0];
    var iCubeNum = optCubes.length
    var iCubeIdx
    
    for (iCubeIdx = 0; iCubeIdx < iCubeNum; iCubeIdx++) {
      optCube = optCubes[iCubeIdx];
      threeUtil.addCube(optCube, hCubes, camera,scene)
    }

    threeUtil.regDrag(dragControls,hCubes, camera,renderer)

    const MOUSE_DOWN = "mouseDown";
    const MOUSE_MOVE = "mouseMove";
    const MOUSE_DOWN_MOVE = "mouseDownMove"; // 按下鼠标并移动
    const MOUSE_DOWNNO_MOVE = "mouseDownNoMove"; // 按下鼠标没有移动
    const MOUSE_NO = "mouseNo";

    var curSelectedMess = null;//当前选择模型
    let raycaster = new THREE.Raycaster();//选择模型的场景射线
    let pointer = new THREE.Vector2(); //鼠标点击的点
    let mouseSceneState = MOUSE_NO;
    var meshDragMarkers = [];//创建拖动的标志物
    var meshDragGroup = new THREE.Group()

    var arrowFront = null;


    //自动模型居中
    var rangeScene = ThreeComm.autoSceneCenterEx(scene,camera);

    //缩放几何体
    window.scaleGeoTest = function(ratio){
      scaleGeo(curSelectedMess,ratio);
    }
    function scaleGeo (geo, ratio) {
      if(ThreeComm.isEmpty(geo)){
        return;
      }
      //geo.faces 属性不存在 行不通

      for (var i = 0; i < geo.faces.length; i++) {
        var faceI = geo.faces[i];
        var vertexArr = [faceI.a, faceI.b, faceI.c];
        for (var j = 0; j < vertexArr.length; j++) {
          var vertexJ = geo.vertices[vertexArr[j]];
          var normalJ = faceI.vertexNormals[j];
          if (vertexJ.hasScale) continue;
          vertexJ.x += normalJ.x * ratio;
          vertexJ.y += normalJ.y * ratio;
          vertexJ.z += normalJ.z * ratio;
          vertexJ.hasScale = true;
        }
      }
      return geo;
    }
    //创建法向量的箭头 https://blog.csdn.net/u014291990/article/details/135322526
    function createArraw(hMess){
      if(ThreeComm.isEmpty(hMess)){
        return
      }
      //已知三角形三个顶点的坐标，计算三角形法线方向
      const p1 = new THREE.Vector3(0, 0, 0);
      const p2 = new THREE.Vector3(50, 0, 0);
      const p3 = new THREE.Vector3(0, 100, 0);
      // 三个顶点构建两个向量，按照三角形顶点的顺序，构建1指向2的向量，2指向3的向量
      const a = p2.clone().sub(p1);
      const b = p3.clone().sub(p2);

      const c = a.clone().cross(b);
      c.normalize();//向量c归一化表示三角形法线方向
      // 可视化向量a和b叉乘结果：向量c
      const arrow = new THREE.ArrowHelper(c, p3, 50, 0xff0000);
      hMess.add(arrow);
    }
    function createOrbitControls(hCamera){
      var controls = new THREE.OrbitControls(hCamera);// 初始化控制器
      controls.target.set(0, 0, 0);// 设置控制器的焦点，使控制器围绕这个焦点进行旋转
      controls.minDistance = 80;// 设置移动的最短距离（默认为零）
      controls.maxDistance = 400;// 设置移动的最长距离（默认为无穷）
      controls.maxPolarAngle = Math.PI / 3;//绕垂直轨道的距离（范围是0-Math.PI,默认为Math.PI）
      controls.update();// 照相机转动时，必须更新该控制器
      return controls;
    }
    // 标注实例 https://blog.51cto.com/u_16099232/11825048
    function addSprite(text, hMess, callback) {
      biaozhudiv = document.createElement('div');
      biaozhudiv.className = 'label';
      biaozhudiv.textContent = text;
      biaozhudiv.onclick = function () {
        callback(hMess)
      };
      biaozhuLabel = new THREE.CSS2DObject(biaozhudiv);
      biaozhuLabel.position.set(0, 0, 0);
      hMess.add(biaozhuLabel);
    }
    function removeCube(hScene,hMess) {
      if(ThreeComm.isEmpty(hMess) || ThreeComm.isEmpty(hMess)){
        return
      }
      hMess.geometry.dispose() // 移除图形数据
      hMess.material.dispose() // 移除材质数据
      // 3. 再从场景中移除物体
      hScene.remove(hMess)
    }
    window.addEventListener('mouseup'  , onSceneMouseUp, false);
    window.addEventListener('mousedown', onSceneMouseDown, false);
    window.addEventListener('mousemove', onSceneMouseMove, false);
    
    window.addEventListener('keydown'  , onScenekeyup, false);

    // var arrowFront,arrowBack
    // arrowFront = new THREE.ArrowHelper(cube.getWorldDirection(), cube.position, 15, 0xFF0000);

    if(null!=orbitControls && typeof(orbitControls)!="undefined"){
      orbitControls.addEventListener( 'drag', function ( event ) {
      })
    }
    
    function onScenekeyup(event){
      var event   = event || window.event;  //标准化事件对象
      var keyCode = event.keyCode;
      var tKey = event.target || event.srcElement;  //获取发生事件的元素，兼容IE和DOM
      var ctrlKey = event.ctrlKey;
      var shiftKey = event.shiftKey;
      var altKey = event.altKey;
      

      if (ctrlKey && shiftKey && altKey) {  //如果同时按下Ctrl和Shift键
        return;
      }
      //没有选择模型退出
      if(null==curSelectedMess){
        return
      }
      //Left arrow（左箭头键）	37	Top arrow（上箭头键）	38  Right arrow（右箭头键）	39	Down arrow（下箭头键）	40
      //非箭头按钮退出
      if(keyCode<37 || keyCode>40){
        return;
      }
      var step = 5;
      var rotation = curSelectedMess.object.rotation
      //按住了Ctrl键，当前模型移动
      if (ctrlKey){
        if(keyCode==37){
          if(altKey){
            curSelectedMess.object.position.z -= step;
          }else {
            curSelectedMess.object.position.x -= step;
          }
        }else if(keyCode==38){
          if(altKey){
            curSelectedMess.object.position.z += step;
          }else{
            curSelectedMess.object.position.y += step;
          }
        }else if(keyCode==39){
          if(altKey){
            curSelectedMess.object.position.z += step;
          }else {
            curSelectedMess.object.position.x += step;
          }
        }else if(keyCode==40){
          if(altKey){
            curSelectedMess.object.position.z -= step;
          }else{
            curSelectedMess.object.position.y -= step;
          }
        }
        curSelectedMess.object.updateMatrix();
        return;
      }
      // 0              1              2          3               4       5
      // 底面          顶面           前面         后面          左面       右面
      //0   1  2  3    4  5  6  7   8  9  10 11 12  13 14 15 16 17 18 20  21  22 23 24 
      //[0, 1, 2, 3], [4, 5, 6, 7],[0, 1, 5, 4],[2, 3, 7, 6],[0, 3, 7, 4],[1, 2, 6, 5] 
      //            0         1        2        3          4         5         6        7
      var faceIdx = 1;
      //按住了Shift键，当前模型增加
      //Left arrow（左箭头键）	37	Top arrow（上箭头键）	38  Right arrow（右箭头键）	39	Down arrow（下箭头键）	40
      if (shiftKey){
        var opt = {};
        if(keyCode==37){
          if(altKey){
            opt.z = -step;
          }else {
            faceIdx = 5;
            opt.x = -step;
          }
        }else if(keyCode==38){
          if(altKey){
            opt.z = step;
          }else {
            faceIdx = 2;
            opt.y = step;
          }
        }else if(keyCode==39){
          if(altKey){
            opt.z = step;
          }else {
            faceIdx = 5;
            opt.x = step;
          }
        }else if(keyCode==40){
          if(altKey){
            opt.z = -step;
          }else {
            faceIdx = 2;
            opt.y = -step;
          }
        }
        adjustMessVertexsByFace(curSelectedMess,faceIdx,opt)
        curSelectedMess.object.updateMatrix();
        return;
      }
    }
    
    function createDragMarkers(hScene,dragMarkers){
      if(null==dragMarkers || dragMarkers.length>0){
        return dragMarkers;
      }
      var dragMarker;
      var opt = {}
      for(let i=0;i<6;i++) {
        opt.faceIdx = i;
        dragMarker = threeUtil.createDragMarker(hScene,opt);
        if(null==dragMarker){
          continue;
        }
        dragMarker.userData = {faceIdx:i,type:'drag'};
        dragMarkers.push(dragMarker)
        meshDragGroup.add(dragMarker);
        hScene.add(meshDragGroup);
      }
      return dragMarkers;
    }

    //创建标记物
    createDragMarkers(scene,meshDragMarkers);
    
    

    function adjustMessVertexsByFace(hMess,faceIdx,opt){
      if(null==hMess || typeof(hMess)=="undefined"){
        return null;
      }
      if(null==opt || typeof(opt)=="undefined"){
        return null;
      }
      if((!ThreeComm.isNum(opt.x) || opt.x==0) && (!ThreeComm.isNum(opt.y) || opt.y==0)  &&(!ThreeComm.isNum(opt.z) || opt.z==0) ){
        return null;
      }

      if(null==faceIdx || typeof(faceIdx)!="number" || faceIdx<0 || faceIdx>5){
        return;
      }
      var hGeometry = ThreeComm.getMessGeometry(hMess);
      if(null==hGeometry || typeof(hGeometry)=="undefined"){
        return null;
      }
      const faces = [
            [0, 1, 2, 3],// 底面            
            [4, 5, 6, 7],// 顶面
            [0, 1, 5, 4],// 前面            
            [2, 3, 7, 6],// 后面            
            [0, 3, 7, 4],// 左面            
            [1, 2, 6, 5] // 右面
        ]; 
      var iIdxs = faces[faceIdx];
      var iSize = iIdxs.length
      var iIdx;
      for(var i=0;i<iSize;i++){
        iIdx = iIdxs[i];
        adjustMessVertexsByPoint(hMess,iIdx,opt);
      }
      hGeometry.verticesNeedUpdate = true;
      hGeometry.getAttribute('position').needsUpdate = true
      hGeometry.computeBoundingBox()
      //取得各个面以及面的中心点
      updateMessMarkerPoints(hMess);
    }
    function adjustMessVertexsByPoint(hMess,iIdx,opt,bModify){
      if(null==hMess || typeof(hMess)=="undefined"){
        console.log('adjustMessVertexsByPoint 模型为空');
        return null;
      }
      if(null==opt || typeof(opt)=="undefined"){
        console.log('adjustMessVertexsByPoint 修改数据为空');
        return null;
      }
      if(!ThreeComm.isNum(iIdx) || iIdx<0 || iIdx>7){
        console.log('adjustMessVertexsByPoint 修改点序号不是数字、或者不在0..7之间');
        return;
      }
      var hGeometry = ThreeComm.getMessGeometry(hMess);
      if(null==hGeometry || typeof(hGeometry)=="undefined"){
        console.log('adjustMessVertexsByPoint 模型的[Geometry]为空');
        return null;
      }
      if(null==hGeometry.attributes || typeof(hGeometry.attributes)=="undefined"){
        console.log('adjustMessVertexsByPoint 模型的[Geometry.attributes]为空');
        return null;
      }
      if(null==hGeometry.attributes.position || typeof(hGeometry.attributes.position)=="undefined"){
        console.log('adjustMessVertexsByPoint 模型的[Geometry.attributes.position]为空');
        return null;
      }
      if(typeof(bModify)!="boolean"){
        bModify = false;
      }
      var x = opt.x;
      var y = opt.y
      var z = opt.z;

      if(null==x || typeof(x)!="number"){
        x = null;
      }
      if(null==y || typeof(y)!="number"){
        y = null;
      }
      if(null==z || typeof(z)!="number"){
        z = null;
      }
      // 0              1             2            3             4         5
      // 底面          顶面           前面         后面          左面       右面
      // 0  1  2  3    4  5  6  7   8  9  10 11 12  13 14 15 16  17 18 19 20  21 22 23 
      //[0, 1, 2, 3], [4, 5, 6, 7],[0, 1, 5, 4],[2, 3, 7, 6],[0, 3, 7, 4],[1, 2, 6, 5] 
      //            0         1        2        3          4         5         6        7
      var pArr = [[0,8,16],[1,9,20],[2,12,21],[3,13,17],[4,11,19],[5,10,23],[6,15,22],[7,14,18]];
      var myAyy = pArr[iIdx]
      var iSize = myAyy.length;
      var vIdx;
      var iPos;
      var myPointArr = [];
      
      for(var i=0;i<iSize;i++){
        vIdx = myAyy[i]
        iPos = vIdx*3;
        if(null!=x ){
          if(bModify){
            hGeometry.attributes.position.array[iPos  ] = x;
          }else{
            hGeometry.attributes.position.array[iPos  ] += x;
          }
        }
        if(null!=y){
          if(bModify){
            hGeometry.attributes.position.array[iPos+1] = y;
          }else{
            hGeometry.attributes.position.array[iPos+1] += y;
          }
        }
        if(null!=z ){
          if(bModify){
            hGeometry.attributes.position.array[iPos+2] = z;
          }else{
            hGeometry.attributes.position.array[iPos+2] += z;
          }
          
        }
      }
    }
    function modifyMessVertexsByPoint(hMess,iIdx,point){
      if(null==hMess || typeof(hMess)=="undefined"){
        console.log('modifyMessVertexsByPoint 模型组件为空')
        return null;
      }
      if(null==point || typeof(point)=="undefined"){
        console.log('modifyMessVertexsByPoint 点坐标为空')
        return null;
      }
      if(null==iIdx || typeof(iIdx)!="number" || iIdx<0 || iIdx>7){
        console.log('modifyMessVertexsByPoint 点序号为空，或者不为数字，或者不在0..7之间')
        return;
      }
      var hGeometry = ThreeComm.getMessGeometry(hMess);
      if(null==hGeometry || typeof(hGeometry)=="undefined"){
        console.log('modifyMessVertexsByPoint 模型的Geometry为空')
        return null;
      }
      if(null==hGeometry.attributes || typeof(hGeometry.attributes)=="undefined"){
        console.log('modifyMessVertexsByPoint 模型的Geometry.attributes为空')
        return null;
      }
      if(null==hGeometry.attributes.position || typeof(hGeometry.attributes.position)=="undefined"){
        console.log('modifyMessVertexsByPoint 模型的Geometry.attributes.position为空')
        return null;
      }
      var x = point.x;
      var y = point.y
      var z = point.z;
      // 底面             顶面         前面          后面         左面         右面
      //     0             1            2            3            4           5
      //[0, 1, 2, 3], [4, 5, 6, 7],[0, 1, 5, 4],[2, 3, 7, 6],[0, 3, 7, 4],[1, 2, 6, 5] 
      //0   1  2  3    4  5  6  7   8  9  10 11 12  13 14 15 16 17 18 20  21  22 23 24 
      var pArr = [[0,8,16],[1,9,21],[2,12,22],[3,13,17],[4,11,20],[5,10,24],[6,15,23],[7,14,18]];
      var myAyy = pArr[iIdx]
      var iSize = myAyy.length;
      var vIdx;
      var iPos;
      var myPointArr = [];
      
      for(var i=0;i<iSize;i++){
        vIdx = myAyy[i]
        iPos = vIdx*3;

        console.log('modifyMessVertexsByPoint iPos=',iPos,' vIdx=',vIdx)
        if(null!=point.x && typeof(point.x)=="number"){
          hGeometry.attributes.position[iPos  ] = point.x;
        }
        if(null!=point.y && typeof(point.y)=="number"){
          hGeometry.attributes.position[iPos+1] = point.y;
        }
        if(null!=point.z && typeof(point.z)=="number"){
          hGeometry.attributes.position[iPos+2] = point.z;
        }
      }
      //hGeometry.attributes.position
    }


    
    function setMessMarkers(hMess){
      if(null==hMess || typeof(hMess)=="undefined"){
        return;
      }
      var messType = ThreeComm.getMessType(hMess);
      if('SphereGeometry'==messType){
        if(null!=dragControls){
          curMarker = hMess;
          //dragControls.enabled = false;
        }
        return
      }
      var points = ThreeComm.getMessPoints(hMess);
      var facePoints;
      var centerPoint;
      var messCenterPoint = ThreeComm.getCenterPoint(points);
      if(null!=meshDragGroup.children){
        var iChild = meshDragGroup.children.length;
        var hChild;
        for(var i=iChild-1;i>=0;i--){
          hChild = meshDragGroup.children[i];
          if(null==hChild || null==hChild.geometry){
            continue;
          }
          if('SphereGeometry'!=hChild.geometry.type){
            meshDragGroup.remove(hChild);
            continue;
          }
        }
      }
      meshDragGroup.visible = true
      hMess.object.add(meshDragGroup);
      //取得各个面以及面的中心点
      updateMessMarkerPoints(hMess);
    }

    function updateMessMarkerPoints(hMess){
      if(null==hMess || typeof(hMess)=="undefined"){
        return;
      }
    
      curFaceIdx = hMess.faceIndex;
      if(!ThreeComm.isNum(curFaceIdx)){
        curFaceIdx = null;
      }
      var points = ThreeComm.getMessPoints(hMess);
      //取得各个面以及面的中心点
      for(var faceIdx=0;faceIdx<6;faceIdx++){
        var facePoints = ThreeComm.getMessFacePoints(hMess,faceIdx,points);
        var centerPoint= ThreeComm.getCenterPoint(facePoints);
        ThreeComm.setMarkerPoint(meshDragMarkers,faceIdx,centerPoint);
      }
      // curMarker = ThreeComm.getObjectByIndex(meshDragMarkers,curFaceIdx);
      // curPosition= ThreeComm.getMessPosition(curMarker);
      // console.log('updateMessMarkerPoints curPosition--',ThreeComm.pointToStr(curPosition),meshDragMarkers)
      // if(ThreeComm.isArray(dragObjects)){
      //   if(dragObjects.length<1){
      //     dragObjects.push(curMarker);
      //   }else{
      //     dragObjects[0] = curMarker;
      //   }
      // }
    }

    function sceneMouseClick(event){
      //完成模型选择
      pointer.x = (event.clientX / window.innerWidth) * 2 - 1;
      pointer.y = - (event.clientY / window.innerHeight) * 2 + 1;
      raycaster.setFromCamera(pointer, camera);
      // 计算物体和射线的焦点
      var intersects = raycaster.intersectObjects(scene.children);
      if (null==intersects || intersects.length<1) {
        return
      }
      var iSize = intersects.length
      var intersect;
      for(var iIdx = 0;iIdx<iSize;iIdx++){
        intersect = intersects[iIdx];
        if(null==intersect){
          continue;
        }
        console.log('intersect.object.type=',intersect.object.type)
        if('Mesh'== intersect.object.type && !ThreeComm.isEmpty(intersect.object)){
          var userData = intersect.object.userData;
          var userType = null;
          if(!ThreeComm.isEmpty(userData)){
            userType = userData.type;
          }
          if('drag'==userType){
            curMarker = intersect;
            return;
          }
          curSelectedMess = intersect;
          var hGeometry = ThreeComm.getMessGeometry(curSelectedMess);
          //console.log('vertexsToStr=',vertexsToStr(hGeometry.attributes.position.array))
          setMessMarkers(curSelectedMess);
          if(null==arrowFront){
            //arrowFront = new THREE.ArrowHelper(curSelectedMess.getWorldDirection(), curSelectedMess.position, 15, 0xFF0000);
            console.log('curSelectedMess',curSelectedMess)
            
            // curSelectedMess.object.updateWorldMatrix(true, true); //更新mesh世界转换矩阵
            // arrowFront = new VertexNormalsHelper(curSelectedMess.object,1, 0xA52A2A);
            // scene.add(arrowFront);
            // curSelectedMess.object.updateWorldMatrix(true, true); //更新mesh世界转换矩阵
            // arrowFront.update();
            // arrowFront.visible = true
            
            // var lambda = 2;
            
          }else{
            //arrowFront.setDirection(curSelectedMess.object.getWorldDirection(new THREE.Vector3()).normalize());
            //arrowFront.position.copy(curSelectedMess.position);
          }

          var userData = curSelectedMess.object.userData;
          if(null!=userData){
            //console.log('userData.data=',JSON.stringify(userData.data))
          }
          break;
        }
      }
    }

    var dragPointStart = null;
    //场景中的按下鼠标
    function onSceneMouseDown(event){
      event.preventDefault();
      mouseSceneState = MOUSE_DOWN
    }
    function onSceneMouseMove(event){
      return;
      event.preventDefault();
      if(null==curSelectedMess || null==curPosition){
        console.log('onSceneMouseMove 02')
        return
      }
      if(!ThreeComm.isNum(curFaceIdx)){
        console.log('onSceneMouseMove 03')
        return;
      }
      var hMarker = ThreeComm.getObjectByIndex(meshDragMarkers,curFaceIdx);
      if(ThreeComm.isEmpty(hMarker)){
        console.log('onSceneMouseMove 04')
        return;
      }
      if(curFaceIdx==2){
        hMarker.position.z = curPosition.z;
        hMarker.position.z = curPosition.z;
      }
      var position= ThreeComm.getMessPosition(curMarker);
      console.log('onSceneMouseMove curFaceIdx',curFaceIdx,'curMarker.userData',hMarker.userData,'position--',ThreeComm.pointToStr(position))
      var dx = ThreeComm.accSub(hMarker.position.x,curPosition.x);
      var dy = ThreeComm.accSub(hMarker.position.y,curPosition.y);
      var dz = ThreeComm.accSub(hMarker.position.z,curPosition.z);

      console.log('onSceneMouseMove curFaceIdx--',curFaceIdx,'dx=',dx,'dy=',dy,'dz=',dz);
      if(curFaceIdx==2){
        adjustMessVertexsByFace(curSelectedMess,5,{x:dx})
        adjustMessVertexsByFace(curSelectedMess,1,{x:dz})
        adjustMessVertexsByFace(curSelectedMess,2,{x:dy})
      }
      
    }
    
    //var markerControls = new DragControls(null,camera, renderer.domElement);


    //场景中的松开鼠标
    function onSceneMouseUp(event){
      event.preventDefault();
      if (mouseSceneState === MOUSE_DOWNNO_MOVE || mouseSceneState === MOUSE_DOWN){
        sceneMouseClick(event);
      }
      mouseSceneState = MOUSE_NO
      dragControls.enabled = true;
    }

    // 禁用 OrbitControls 在拖动过程中
    dragControls.addEventListener('drag', function (event) {
      var hDragObj = event.object;
      var userType = ThreeComm.getMessUserDataType(hDragObj);
      console.log('dragControls onSceneMouseMove event.object userType=',userType,'hDragObj=',hDragObj)

      if(null==curSelectedMess){
        console.log('dragControls onSceneMouseMove 选择的模型为空',event)
        return
      }
      
      var userData = ThreeComm.getMessUserData(hDragObj);
      var faceIdx  = null;
      if(!ThreeComm.isEmpty(userData)){
        faceIdx  = userData.faceIdx;
      }
      if(!ThreeComm.isNum(faceIdx) || faceIdx<0 || faceIdx>5){
        console.log('dragControls onSceneMouseMove faceIdx=',faceIdx)
        return;
      }
      var position  = ThreeComm.getMessPosition(hDragObj);
      
      console.log('dragControls onSceneMouseMove position--',ThreeComm.pointToStr(position),ThreeComm.pointToStr(curPosition))
      var points = ThreeComm.getMessPoints(curSelectedMess);
      var lambda = getScaleByFace(points,faceIdx,position);
      adjustMessByFaceLambda(curSelectedMess,faceIdx,lambda);
      updateMessMarkerPoints(curSelectedMess)
      console.log('onSceneMouseMove curFaceIdx--',curFaceIdx,'faceIdx=',faceIdx,'lambda=',lambda);
    });

    window.adjustMessByFaceLambdaTest = function(faceIdx,lambda){
      adjustMessByFaceLambda(curSelectedMess,faceIdx,lambda);
    }
    

    function adjustMessByFaceLambda(hMess,faceIdx,lambda){
      var hGeometry = ThreeComm.getMessGeometry(hMess);
      if(ThreeComm.isEmpty(hGeometry)){
        console.log('adjustMessByFaceLambda模型不存在')
        return;
      }
      var points = ThreeComm.getMessPoints(hMess);
      if(!ThreeComm.isArray(points)){
        console.log('adjustMessByFaceLambda 取得模型points为空')
        return;
      }
      var edges  = ThreeComm.getFaceEdgePoints(points,faceIdx);
      var iSize  = 0;
      if(ThreeComm.isArray(edges)){
        iSize = edges.length
      }
      var edge,p1,p2,p3;

      console.log('adjustMessByFaceLambda points--',points,'lambda=',lambda,'edge=',edge);
      for(var i=0;i<iSize;i++){
        edge = edges[i]
        p1 = edge[0]
        p2 = edge[1]
        p3 = ThreeComm.getLambdaPoint(p1,p2,lambda)
        
        adjustMessVertexsByPoint(hMess,p3.idx_,p3,true)     
      }
      hGeometry.verticesNeedUpdate = true;
      hGeometry.getAttribute('position').needsUpdate = true
      hGeometry.computeBoundingBox()
    }

    // 底面             顶面         前面          后面         左面         右面
    //     0             1            2            3            4           5
    //[0, 1, 2, 3], [4, 5, 6, 7],[0, 1, 5, 4],[2, 3, 7, 6],[0, 3, 7, 4],[1, 2, 6, 5] 
    //0   1  2  3    4  5  6  7   8  9  10 11 12  13 14 15 16 17 18 20  21  22 23 24 
    function getScaleByFace(points,faceIdx,point){
      if(!ThreeComm.isArray(points)){
          console.log('getScaleByFace points is not Array points=',points,ThreeComm.isArray(points))
          return 0;
        }
        if(!ThreeComm.isNum(faceIdx)){
          console.log('getScaleByFace faceIdx is not Num')
          return 0;
        }
        if(!ThreeComm.isPoint(point)){
          console.log('getScaleByFace point is not Point')
          return 0;
        }
        var p1 = null;
        var p2 = null;
        var faceIdx0 = ThreeComm.getOppositeFaceIdx(faceIdx);
        if(faceIdx0<0){
          return 0;
        }
        var point1 = ThreeComm.getFaceCenterPoint(points,faceIdx0);
        var point2 = ThreeComm.getFaceCenterPoint(points,faceIdx);
        var point3 = ThreeComm.getFootOfPerpendicular(point,point1,point2);
        if(!ThreeComm.isPoint(point3)){
          console.log('getScaleByFace point3 is not Point point3=',point3)
          return 0;
        }
        var dis1 = ThreeComm.twoPointDistance(point1,point2);
        var dis2 = ThreeComm.twoPointDistance(point1,point3);
        console.log('dis1=',dis1,'dis2=',dis2)
        if(dis1==0){
          return 0;
        }
        var result = ThreeComm.accDiv(dis2,dis1); 
        return result;
    }
  </script>

</body>

</html>